{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Deep Learning Models -- A collection of various deep learning architectures, models, and tips for TensorFlow and PyTorch in Jupyter Notebooks.\n",
    "- Author: Sebastian Raschka\n",
    "- GitHub Repository: https://github.com/rasbt/deeplearning-models"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Sebastian Raschka \n",
      "\n",
      "CPython 3.6.1\n",
      "IPython 6.0.0\n",
      "\n",
      "tensorflow 1.2.0\n"
     ]
    }
   ],
   "source": [
    "%load_ext watermark\n",
    "%watermark -a 'Sebastian Raschka' -v -p tensorflow"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Model Zoo -- Convolutional Autoencoder with Nearest-neighbor Interpolation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A convolutional autoencoder using nearest neighbor upscaling layers that compresses 768-pixel MNIST images down to a 7x7x4 (196 pixel) representation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Extracting ./train-images-idx3-ubyte.gz\n",
      "Extracting ./train-labels-idx1-ubyte.gz\n",
      "Extracting ./t10k-images-idx3-ubyte.gz\n",
      "Extracting ./t10k-labels-idx1-ubyte.gz\n"
     ]
    }
   ],
   "source": [
    "import tensorflow as tf\n",
    "from tensorflow.examples.tutorials.mnist import input_data\n",
    "\n",
    "\n",
    "##########################\n",
    "### DATASET\n",
    "##########################\n",
    "\n",
    "mnist = input_data.read_data_sets(\"./\", validation_size=0)\n",
    "\n",
    "\n",
    "##########################\n",
    "### SETTINGS\n",
    "##########################\n",
    "\n",
    "# Hyperparameters\n",
    "learning_rate = 0.001\n",
    "training_epochs = 5\n",
    "batch_size = 128\n",
    "\n",
    "# Architecture\n",
    "input_size = 784\n",
    "image_width = 28\n",
    "\n",
    "# Other\n",
    "print_interval = 200\n",
    "random_seed = 123\n",
    "\n",
    "\n",
    "##########################\n",
    "### GRAPH DEFINITION\n",
    "##########################\n",
    "\n",
    "g = tf.Graph()\n",
    "with g.as_default():\n",
    "    \n",
    "    tf.set_random_seed(random_seed)\n",
    "\n",
    "    # Input data\n",
    "    tf_x = tf.placeholder(tf.float32, [None, input_size], name='inputs')\n",
    "    input_layer = tf.reshape(tf_x, shape=[-1, image_width, image_width, 1])\n",
    "\n",
    "    ###########\n",
    "    # Encoder\n",
    "    ###########\n",
    "    \n",
    "    # 28x28x1 => 28x28x8\n",
    "    conv1 = tf.layers.conv2d(input_layer, filters=8, kernel_size=(3, 3),\n",
    "                             strides=(1, 1), padding='same', \n",
    "                             activation=tf.nn.relu)\n",
    "    \n",
    "    # 28x28x8 => 14x14x8\n",
    "    maxpool1 = tf.layers.max_pooling2d(conv1, pool_size=(2, 2), \n",
    "                                       strides=(2, 2), padding='same')\n",
    "    \n",
    "    # 14x14x8 => 14x14x4\n",
    "    conv2 = tf.layers.conv2d(maxpool1, filters=4, kernel_size=(3, 3), \n",
    "                             strides=(1, 1), padding='same', \n",
    "                             activation=tf.nn.relu)\n",
    "    \n",
    "    # 14x14x4 => 7x7x4\n",
    "    encode = tf.layers.max_pooling2d(conv2, pool_size=(2, 2), \n",
    "                                     strides=(2, 2), padding='same', \n",
    "                                     name='encoding')\n",
    "\n",
    "    ###########\n",
    "    # Decoder\n",
    "    ###########\n",
    "    \n",
    "    # 7x7x4 => 14x14x4\n",
    "    deconv1 = tf.image.resize_nearest_neighbor(encode, \n",
    "                                               size=(14, 14))\n",
    "    # 14x14x4 => 14x14x8\n",
    "    conv3 = tf.layers.conv2d(deconv1, filters=8, kernel_size=(3, 3), \n",
    "                             strides=(1, 1), padding='same', \n",
    "                             activation=tf.nn.relu)\n",
    "    \n",
    "    # 14x14x8 => 28x28x8\n",
    "    deconv2 = tf.image.resize_nearest_neighbor(conv3, \n",
    "                                               size=(28, 28))\n",
    "    # 28x28x8 => 28x28x8\n",
    "    conv4 = tf.layers.conv2d(deconv2, filters=8, kernel_size=(3, 3), \n",
    "                             strides=(1, 1), padding='same', \n",
    "                             activation=tf.nn.relu)\n",
    "    # 28x28x8 => 28x28x1\n",
    "    logits = tf.layers.conv2d(conv4, filters=1, kernel_size=(3,3), \n",
    "                              strides=(1, 1), padding='same', \n",
    "                              activation=None)\n",
    "    \n",
    "    decode = tf.nn.sigmoid(logits, name='decoding')\n",
    "\n",
    "    ##################\n",
    "    # Loss & Optimizer\n",
    "    ##################\n",
    "    \n",
    "    loss = tf.nn.sigmoid_cross_entropy_with_logits(labels=input_layer,\n",
    "                                                   logits=logits)\n",
    "    cost = tf.reduce_mean(loss, name='cost')\n",
    "    optimizer = tf.train.AdamOptimizer(learning_rate)\n",
    "    train = optimizer.minimize(cost, name='train')    \n",
    "\n",
    "    # Saver to save session for reuse\n",
    "    saver = tf.train.Saver()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Minibatch: 001 | Cost:    0.724\n",
      "Minibatch: 201 | Cost:    0.124\n",
      "Minibatch: 401 | Cost:    0.103\n",
      "Epoch:     001 | AvgCost: 0.181\n",
      "Minibatch: 001 | Cost:    0.101\n",
      "Minibatch: 201 | Cost:    0.097\n",
      "Minibatch: 401 | Cost:    0.092\n",
      "Epoch:     002 | AvgCost: 0.093\n",
      "Minibatch: 001 | Cost:    0.089\n",
      "Minibatch: 201 | Cost:    0.085\n",
      "Minibatch: 401 | Cost:    0.089\n",
      "Epoch:     003 | AvgCost: 0.087\n",
      "Minibatch: 001 | Cost:    0.085\n",
      "Minibatch: 201 | Cost:    0.088\n",
      "Minibatch: 401 | Cost:    0.085\n",
      "Epoch:     004 | AvgCost: 0.084\n",
      "Minibatch: 001 | Cost:    0.088\n",
      "Minibatch: 201 | Cost:    0.082\n",
      "Minibatch: 401 | Cost:    0.085\n",
      "Epoch:     005 | AvgCost: 0.083\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "##########################\n",
    "### TRAINING & EVALUATION\n",
    "##########################\n",
    "    \n",
    "with tf.Session(graph=g) as sess:\n",
    "    sess.run(tf.global_variables_initializer())\n",
    "\n",
    "    np.random.seed(random_seed) # random seed for mnist iterator\n",
    "    for epoch in range(training_epochs):\n",
    "        avg_cost = 0.\n",
    "        total_batch = mnist.train.num_examples // batch_size\n",
    "\n",
    "        for i in range(total_batch):\n",
    "            batch_x, batch_y = mnist.train.next_batch(batch_size)\n",
    "            _, c = sess.run(['train', 'cost:0'], feed_dict={'inputs:0': batch_x})\n",
    "            avg_cost += c\n",
    "\n",
    "            if not i % print_interval:\n",
    "                print(\"Minibatch: %03d | Cost:    %.3f\" % (i + 1, c))\n",
    "\n",
    "        print(\"Epoch:     %03d | AvgCost: %.3f\" % (epoch + 1, avg_cost / (i + 1)))\n",
    "    \n",
    "    saver.save(sess, save_path='./autoencoder.ckpt')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Restoring parameters from ./autoencoder.ckpt\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAABIEAAACqCAYAAAA6El8nAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJztnXe4VNX5hd8TE00xVhSxIBYsxC52sbdgwY4dK/ZeoibY\njb0bReyoUexij2Lvgl2xYI3YW+w/Yzy/P2CdvWfuvXDm3umz3ufhucOZc2f2fHfvffacb+31JWma\nYowxxhhjjDHGGGOam1/VugHGGGOMMcYYY4wxpvL4JpAxxhhjjDHGGGNMC+CbQMYYY4wxxhhjjDEt\ngG8CGWOMMcYYY4wxxrQAvglkjDHGGGOMMcYY0wL4JpAxxhhjjDHGGGNMC+CbQMYYY4wxxhhjjDEt\nQJduAiVJsk6SJK8lSTIuSZJDy9UoY4wxxhhjjDHGGFNekjRNO/eLSTIF8DqwJvA+8DSwZZqmr5Sv\necYYY4wxxhhjjDGmHPy6C7+7NDAuTdO3AJIkuQYYAHR4E6hbt25pr169uvCWjcuYMWM+S9N0przn\nO1aOVR5KjRW0brwcq9LwOMyPY5Ufj8P8OFal4XGYH8cqPx6H+XGs8uNYlYbnrPzkjVVXbgLNBvw7\n+v/7wDLFJyVJMhgYDNCzZ09Gjx7dhbdsXJIkeTfHOY4VjlUp5InVxPNaPl6OVWl4HObHscqPx2F+\nHKvS8DjMj2OVH4/D/DhW+XGsSsNzVn7y9q2KG0OnaTosTdO+aZr2nWmmkm54thyOVX4cq9JwvPLj\nWOXHscqPY1Uajld+HKv8OFb5caxKw/HKj2OVH8cqP45VaXTlJtB4YI7o/7NPPGaMMcYYY4wxxhhj\n6oyu3AR6GuidJMlcSZJMCWwBjCxPs4wxxhhjjDHGGGNMOem0J1Capj8nSbIXcDcwBXBJmqYvl61l\nxhhjjDHGGGOMMaZsdMUYmjRN7wDuKFNbjDHGGGOMMcYYY0yF6NJNINOYnHrqqQD88MMP2bEXXngB\ngOuvv77g3N133x2A5ZZbLju27bbbVrqJxhhjjDHGmIn83//9HwDLL798duzZZ58FYIMNNgDg5ptv\nrn7DjDENR8WrgxljjDHGGGOMMcaY2mMlUAsxcOBAAK677roOz0mSpOD/Q4cOBeDee+/Njq288soA\n9OzZs9xNbApef/317PH8888PwNlnnw3A3nvvXZM21YrvvvsOgIMPPhgI/alv375AYV+cc845q9w6\nY4wx1eDLL78E4L333mv3+Xj+P+OMMwBYaKGFAJhvvvkAWHTRRSvZRFNjHn744eyxlC6vvfYaALfd\ndhsAt99+OwDrrrtum9+XYr1fv34VbWctkAJo//33B+C5557LntO6fckll6x+w4wxBRx11FEAHH30\n0QCsssoqANx///01alHHWAlkjDHGGGOMMcYY0wJYCdQC5FEALbDAAgCss846ALz11lsAjBw5EoBx\n48Zl51555ZUAHH744eVvbBOg/dkAv/rVhPuss802W62aU1M++OADAC688EIApphiCgBGjx4NwK23\n3pqdu9dee1W5dbXjmWeeAWDjjTfOjr3zzjudfr1//etfACy44IIAzDHHHJ1vXJMQ9y15JZxzzjlA\n8DpTf2wGPvnkEwA233xzoNAzYvDgwQD06tWry+/zn//8J3v80EMPAeG68Zvf/KbLr28aH6k24jH4\nwAMPAPDGG2+0+ztSzUKYC6V+EL/88ksZW2lqzddffw3A1ltvDcCoUaOy5373u98B8N///heAb775\npuB3NffE6Hf+8Ic/AHD++ecDsOmmm5az2TVBavILLrgAgNVXXz177phjjgFg2WWXrX7DTNMi9aa+\n09x1110AnHLKKUDhzpHNNtsMCIrOAw88EIDu3btXp7F1xIMPPljwf1379BOCOqjWWAlkjDHGGGOM\nMcYY0wJYCdSkSGkBcNNNNxU8p332UvkAdOvWDYCpp54agJ9++gmAZZZZBoDnn38+O/fzzz+vQIub\nh3ivtuIZKz6anU8//TR7PGjQoBq2pH65++67gbaZ7s6isXzJJZcAcM0115TldRsRzU9S+8TIk2un\nnXYCQua4kVG27k9/+hMQlDpxBq6cCqAlllgiO/bZZ58B4XrTu3fvLr9PLZAiAeDQQw8F4OWXXwaC\nH55VTm158803AfjHP/4BwLBhw4BQeTRN09yvJe8X0zr85S9/AYJyLEZ9SOrWmWeeGYBpppmmzblS\niMkvSL+reV6eUgCLLLJIWdpebT788MOC/6+xxhrZYyuATFeR4u60007Ljp177rlA274nBVCsBCqu\nLK21gdakrUSs+OnouJVAxhhjjDHGGGOMMaZq1L0SSHcX5SkCMOusswLw29/+Fgj7iWeZZZbsnHnn\nnbdaTaxL4ju3ysZJASQVQo8ePTr8/VNPPRWAsWPHtnluvfXWK1s7m4kXX3wRCL4jANttt12tmlN1\n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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x127163748>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "##########################\n",
    "### VISUALIZATION\n",
    "##########################\n",
    "\n",
    "n_images = 15\n",
    "\n",
    "fig, axes = plt.subplots(nrows=2, ncols=n_images, sharex=True, \n",
    "                         sharey=True, figsize=(20, 2.5))\n",
    "test_images = mnist.test.images[:n_images]\n",
    "\n",
    "with tf.Session(graph=g) as sess:\n",
    "    saver.restore(sess, save_path='./autoencoder.ckpt')\n",
    "    decoded = sess.run('decoding:0', feed_dict={'inputs:0': test_images})\n",
    "\n",
    "for i in range(n_images):\n",
    "    for ax, img in zip(axes, [test_images, decoded]):\n",
    "        ax[i].imshow(img[i].reshape((image_width, image_width)), cmap='binary')"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
